package top.yamhk.agent;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;

/**
 * 服务器资源监控服务
 * 监控CPU和内存使用情况，当达到阈值时暂停服务
 */
@Slf4j
@Service
public class ServerMonitorService {
    
    /**
     * 资源使用阈值（80%）
     */
    private static final double THRESHOLD = 80.0;
    
    /**
     * 是否系统满载
     */
    private volatile boolean systemOverloaded = false;
    
    /**
     * 最近一次检查时间
     */
    private volatile long lastCheckTime = 0;
    
    /**
     * 最近一次CPU使用率
     */
    private volatile double lastCpuUsage = 0.0;
    
    /**
     * 最近一次内存使用率
     */
    private volatile double lastMemoryUsage = 0.0;
    
    /**
     * 检查服务器资源使用情况
     * 每5秒执行一次
     */
    @Scheduled(fixedDelay = 5000)
    public void checkSystemResources() {
        try {
            // 获取操作系统MXBean
            OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
            
            // 获取内存MXBean
            MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
            
            // 获取CPU使用率
            double cpuUsage = 0.0;
            if (osBean instanceof com.sun.management.OperatingSystemMXBean) {
                // 尝试获取更准确的CPU使用率
                double processCpuLoad = ((com.sun.management.OperatingSystemMXBean) osBean).getProcessCpuLoad();
                if (processCpuLoad >= 0) {
                    cpuUsage = processCpuLoad * 100;
                }
            }
            
            // 获取内存使用情况
            long heapUsed = memoryBean.getHeapMemoryUsage().getUsed();
            long heapMax = memoryBean.getHeapMemoryUsage().getMax();
            double memoryUsage = (double) heapUsed / heapMax * 100;
            
            // 更新最近检查时间和资源使用率
            lastCheckTime = System.currentTimeMillis();
            lastCpuUsage = cpuUsage;
            lastMemoryUsage = memoryUsage;
            
            // 检查是否超过阈值
            if (cpuUsage >= THRESHOLD || memoryUsage >= THRESHOLD) {
                if (!systemOverloaded) {
                    systemOverloaded = true;
                    log.warn("系统满载警告: CPU使用率={}%，内存使用率={}%，已暂停服务", 
                            String.format("%.2f", cpuUsage), String.format("%.2f", memoryUsage));
                }
            } else {
                if (systemOverloaded) {
                    systemOverloaded = false;
                    log.info("系统恢复正常: CPU使用率={}%，内存使用率={}%，已恢复服务", 
                            String.format("%.2f", cpuUsage), String.format("%.2f", memoryUsage));
                }
            }
        } catch (Exception e) {
            log.error("检查系统资源时发生错误", e);
        }
    }
    
    /**
     * 检查系统是否满载
     * @return true表示系统满载，false表示正常
     */
    public boolean isSystemOverloaded() {
        return systemOverloaded;
    }
    
    /**
     * 获取系统监控信息
     * @return 监控信息
     */
    public SystemMonitorInfo getSystemMonitorInfo() {
        SystemMonitorInfo info = new SystemMonitorInfo();
        info.setOverloaded(systemOverloaded);
        info.setCpuUsage(lastCpuUsage);
        info.setMemoryUsage(lastMemoryUsage);
        info.setLastCheckTime(lastCheckTime);
        info.setThreshold(THRESHOLD);
        return info;
    }
    
    /**
     * 系统监控信息类
     */
    public static class SystemMonitorInfo {
        private boolean overloaded;
        private double cpuUsage;
        private double memoryUsage;
        private long lastCheckTime;
        private double threshold;
        
        // Getters and Setters
        public boolean isOverloaded() {
            return overloaded;
        }
        
        public void setOverloaded(boolean overloaded) {
            this.overloaded = overloaded;
        }
        
        public double getCpuUsage() {
            return cpuUsage;
        }
        
        public void setCpuUsage(double cpuUsage) {
            this.cpuUsage = cpuUsage;
        }
        
        public double getMemoryUsage() {
            return memoryUsage;
        }
        
        public void setMemoryUsage(double memoryUsage) {
            this.memoryUsage = memoryUsage;
        }
        
        public long getLastCheckTime() {
            return lastCheckTime;
        }
        
        public void setLastCheckTime(long lastCheckTime) {
            this.lastCheckTime = lastCheckTime;
        }
        
        public double getThreshold() {
            return threshold;
        }
        
        public void setThreshold(double threshold) {
            this.threshold = threshold;
        }
    }
}